Program CommandLineRPG;

Uses
  Crt,
  //SELF MADE UNITS
  DefaultClasses, Enemies, xpTABLE, DamageCalc,
  MenuDraw, Initializer, Abilities, Items, ItemProperties, EnA;


Var
  //STRINGS
  HeroName : String;

  //INTEGERS

  //BOOLEAN

  //CHARS
  MenuAction, InnAction : Char;

{##########################}
//PROCEDURES AND FUNCTIONS\\
{##########################}

Procedure CreateAChar;
Var ClassChoice, Choice : Char;

Label
  class_selection;

 Begin
   Writeln('Welcome to character creation');
   Writeln('From here, you can create a character');
   Repeat
     Writeln('What is your name?');
     Readln(HeroName);
     If HeroName = '' then
       Writeln('Nothing typed, Enter a name');
   Until HeroName <> '';

   Writeln;
   Writeln('You are now able to choose from 3 different Classes;');

   class_selection: //Return to this point if wish to re-select class.
   Clrscr;
   Writeln('Character Name: ',HeroName);
   Writeln;
   Writeln('W - Warrior - Favours Strength and high HP');
   Writeln('M - Mage - Has high wisdom, though lower HP than normal');
   Writeln('A - Archer - Has a higher crit chance than normal');
   Writeln;

   Repeat
     Writeln('Which is your calling? (w, m or a) ');
     ClassChoice := Readkey;
   Until (ClassChoice = 'w') or (ClassChoice = 'm') or (ClassChoice = 'a') or
         (ClassChoice = 'W') or (ClassChoice = 'M') or (ClassChoice = 'A');

   If (ClassChoice = 'w') or (ClassChoice = 'W') then
     Begin
       ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
       WarriorClass;
       Repeat
         Writeln('You have chosen Warrior, is this correct? (Y or N) ');
         Choice := Readkey;
         If (Choice = 'N') or (Choice = 'n') then
           Begin
             ClrScr;
             ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
             Goto class_selection; //Goto used to return if the player doesn't want that class.
         end;
       Until (Choice = 'Y') or (Choice = 'y');
     end;

   If (ClassChoice = 'A') or (ClassChoice = 'a') then
     Begin
       ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
       ArcherClass;
       Repeat
         Writeln('You have chosen Archer, is this correct? (Y or N) ');
         Choice := Readkey;
         If (Choice = 'N') or (Choice = 'n') then
           Begin
             ClrScr;
             ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
             Goto class_selection; //Goto used to return if the player doesn't want that class.
         end;
       Until (Choice = 'Y') or (Choice = 'y');
     end;

   If (ClassChoice = 'm') or (ClassChoice = 'M') then
     Begin
       ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
       MageClass;
       Repeat
         Writeln('You have chosen Mage, is this correct? (Y or N) ');
         Choice := Readkey;
         If (Choice = 'N') or (Choice = 'n') then
           Begin
             ClrScr;
             ClassReset(Health, Hp, Strength, Agility, Wisdom, Mana, MP, Rage, Energy);
             Goto class_selection; //Goto used to return if the player doesn't want that class.
         end;
       Until (Choice = 'Y') or (Choice = 'y');
     end;
end;

Procedure PlayerLog(Gold : Integer);
 Begin
   Clrscr;
   Writeln('Name: ',HeroName);
   Writeln('Class: ',ClassType);
   Writeln('Hit Points: ',HP);
   Writeln('Current Health: ',Health);
   If ClassType = 'Mage' then
     Begin
       Writeln('Mana Points: ',MP);
       Writeln('Current Mana: ',Mana);
     end;
   Writeln('Strength: ',Strength);
   Writeln('Agility: ',Agility);
   Writeln('Wisdom: ',Wisdom);
   Writeln('Experience Points: ',EXP);
   Writeln('Level: ',Level);
   Writeln('Gold: ',Gold);

   Attention;
 end;

Procedure Save(ClassType : String;
               Rage, MP, Energy : Integer;
               HeroName : String;
               HP, Health, Mana, Strength, Agility, Wisdom, EXP, Level, Gold : Integer;
               DItem : Array of DynamicItemMenu);
Var
  CurrentFile : Text;
  Location : String;
  Count, Resource : Integer;

 Begin
   Count := 1;
  try
   If ClassType = 'Warrior' then
     Resource := Rage;

   If ClassType = 'Mage' then
     Resource := MP;

   If ClassType = 'Archer' then
     Resource := Energy;

    Location := ('clrpg.stats');
    Assign(CurrentFile, Location);
    Rewrite(CurrentFile);
    Writeln(CurrentFile, HeroName);
    Writeln(CurrentFile, ClassType);
    Writeln(CurrentFile, HP);
    Writeln(CurrentFile, Health);
    Writeln(CurrentFile, Resource);
    If ClassType = 'Mage' then
      Writeln(CurrentFile, Mana);
    Writeln(CurrentFile, Strength);
    Writeln(CurrentFile, Agility);
    Writeln(CurrentFile, Wisdom);
    Writeln(CurrentFile, EXP);
    Writeln(CurrentFile, Level);
    Writeln(CurrentFile, Gold);
    Repeat
      If DItem[Count].ItemAmount >= 1 then
        Begin
          Writeln(CurrentFile, DItem[Count].Name);
          Writeln(CurrentFile, DItem[Count].ItemAmount);
          Writeln(CurrentFile, DItem[Count].ItemID);
          Count := Count + 1;
          Continue
        end else
          Break;
    until {DItem[Count].ItemAmount = 0} Count = 99;
    CloseFile(CurrentFile);
   except
    Writeln('failed to save');
    Attention;
    exit;
   end;

    Writeln('Save file successfully written, returning to previous menu..');
    Delay(1250);
 end;

Procedure Load(Var HeroName, ClassType : String;
               Var HP, Health, Mana, Strength, Agility, Wisdom, EXP, Level, Gold, Rage, MP, Energy : Integer;
               Var DItem : Array of DynamicItemMenu);
Var
  CurrentFile : Text;
  Location : String;
  Resource, Count : Integer;
 Begin
  Count := 1;
  try
   Location := ('clrpg.stats');
   Assign(CurrentFile, Location);
   Reset(CurrentFile);
   Readln(CurrentFile, HeroName);
   Readln(CurrentFile, ClassType);
   Readln(CurrentFile, HP);
   Readln(CurrentFile, Health);
   Readln(CurrentFile, Resource);
   If ClassType = 'Mage' then
     Readln(CurrentFile, Mana);
   Readln(CurrentFile, Strength);
   Readln(CurrentFile, Agility);
   Readln(CurrentFile, Wisdom);
   Readln(CurrentFile, EXP);
   Readln(CurrentFile, Level);
   Readln(CurrentFile, Gold);
   Repeat
      If DItem[Count].ItemAmount >= 1 then
        Begin
          Readln(CurrentFile, DItem[Count].Name);
          Readln(CurrentFile, DItem[Count].ItemAmount);
          Readln(CurrentFile, DItem[Count].ItemID);
          Count := Count + 1;
          Continue
        end else
          Break;
    until {DItem[Count].ItemAmount = 0} Count = 99;
   CloseFile(CurrentFile);

   If ClassType = 'Warrior' then
     Rage := Resource;

   If ClassType = 'Mage' then
     MP := Resource;

   If ClassType = 'Archer' then
     Energy := Resource;
  except
    Writeln('EXCEPTION RAISED - failed to load save file - it has probably been modified in a bad way. Delete it and create a new save');
    Attention;
    exit;
  end;

   Writeln('File Loaded, returning to previous menu..');
   Delay(1250);

 end;
Procedure Rest(Var Health, HP : Integer; ClassType : String; Var Mana, MP, Energy : Integer; Ailment1, Ailment2 : String);
Begin
  Health := HP;
  If ClassType = 'Mage' then
    Mana := MP;
  If ClassType = 'Archer' then
    Energy := 100;
  Ailment1 := '';
  Ailment2 := '';
end;

Procedure INNMenu(Var Health, Mana, MP, HP : Integer; Hit : Boolean; Var Gold : Integer; EHP : Integer);
 Begin
   Repeat
     If Health < 0 then
       Mana := MP;
     If Health < 0 then
       Health := Hp;
     If Health > HP then
       Health := Hp;
     If LevelledUp then
       Rest(Health, Hp, ClassType, Mana, MP, Energy,Ailment1, Ailment2);

     Writeln('Welcome to the Inn');
     Writeln('What would you like to do?');
     Writeln('1 - Battle');
     Writeln('2 - Rest');
     Writeln('3 - Shop');
     Writeln('4 - Player Log');
     Writeln('5 - View Inventory');
     Writeln('6 - Save');
     Writeln('9 - Exit');
     InnAction := Readkey;

     Case InnAction of
       #49 : Fight(Hit, EHP, Health, HeroName, Gold,  Mana);
       #50 : Rest(Health, HP, ClassType, Mana, MP, Energy, Ailment1, Ailment2);
       #51 : GeneralShop;
       #52 : PlayerLog(Gold);
       #53 : ItemDisplay;
       #54 : Save(ClassType, Rage, MP, Energy, HeroName, HP, Health, Mana, Strength, Agility, Wisdom, EXP, Level, Gold, DItem);
       #57 :
     end;

   Clrscr;

   Until InnAction = #57 ;
 end;


//PROGRAM BODY BEGINS HERE
Begin
 Clrscr;
 Randomize;

 //Pre-release introduction.
 Window(18,8,62,18);
 TextBackground(000111);
 Clrscr;
 Window(20,9,60,17);
 TextBackground(Red);
 Clrscr;

 Writeln;
 Writeln('            Welcome to clRPG');
 Writeln;
 Writeln(' A simple command-line RPG');
 Writeln(' At the moment, the game will consist of');
 Writeln(' an infinite amount of waves where you');
 Writeln(' will choose what attack in order to ');
 Writeln(' kill the enemy');

 Window(1,1,80,25);
 Attention;

 AbilitySetup; //Initiates the ability arrays for use.
 ItemNameSetup; //Initiates the Item Names for use.
 ItemIDSetup; //Initiates the Item ID Numbers for use.
 ItemPriceSetup; //Initiates the Item Prices for use.
 InventorySetup_amountonly; //Initiates ItemAmount array for use.

 Repeat
   Menu;
   TextColor(White);
   TextBackground(0);
   MenuAction := Readkey;
   clrscr;

   Case MenuAction of
     #49 : Begin
             If ClassType = '' then
               Begin
                 Writeln('You need to create a character or load one to play');
                 Attention_noclear
               end else
                 InnMenu(Health, Mana, MP, HP, Hit, Gold, HP);
           end;
     #50 : CreateAChar;
     #51 : Save(ClassType, Rage, MP, Energy, HeroName, HP, Health, Mana, Strength, Agility, Wisdom, EXP, Level, Gold, DItem);
     #52 : Load(HeroName, ClassType, HP, Health, Mana, Strength, Agility, Wisdom, EXP, Level, Gold, Rage, MP, Energy, DItem);
     #53 : PlayerLog(Gold);
   end;

   TextBackground(0);

 Until MenuAction = #57;

end.
